<#include "macro_.ftl">
package ${packageCode}.${moduleMapperKey}.service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.Setter;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;

import com.cardone.common.dto.PaginationDto;
import com.cardone.persistent.CommonDtoAttributes;
import com.cardone.common.utils.EntityUtils;
import ${packageCode}.${moduleMapperKey}.dao.${businessCode}Dao;
<#list entityMapperList as entityMapper>
<#if (entityMapper.code!) != (businessCode!)>
import ${packageCode}.${moduleMapperKey}.dao.${entityMapper.code}Dao;
</#if>
<#if entityMapper.markService>
import ${packageCode}.${moduleMapperKey}.dto.${entityMapper.code}Dto;
</#if>
</#list>

/**
 * ${businessMapper.name!businessCode}服务
 *
 * @author ${author!'yaoht'}
 * 
 */
@Getter 
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class ${businessCode}DefaultService implements ${businessCode}Service {
	/**
	 * ${businessMapper.name!businessCode}数据持久
	 */
	private ${businessCode}Dao ${businessCode?uncap_first}Dao;
<#list entityMapperList as entityMapper>
<#if (entityMapper.code!) != (businessCode!)>

	/**
	 * ${entityMapper.remarks!entityMapper.code}数据持久
	 */
	private ${(entityMapper.code!)}Dao ${(entityMapper.code!)?uncap_first}Dao;
</#if>
</#list>
	
	@Override
	@CacheEvict(value = ${businessCode}Service.BEAN_ID, allEntries = true)
	public void reload() {
	    this.${businessCode?uncap_first}Dao.reload();
<#list entityMapperList as entityMapper>
<#if (entityMapper.code!) != (businessCode!)>

	    this.${(entityMapper.code!)?uncap_first}Dao.reload();
</#if>
</#list>
	}
<#if businessCode == (moduleMapperKey?cap_first)>
<#list moduleMapper.businessMap?values as localBusiness>
<#if (localBusiness.code!) != (moduleMapperKey?cap_first)>

	/**
	 * ${localBusiness.name!localBusiness.code}服务
	 */
	private ${localBusiness.code!}Service ${localBusiness.code?uncap_first}Service;
</#if>
</#list>
</#if>
<#list entityMapperList as entityMapper>
<#if entityMapper.markService>

	@Override
	@Transactional
	@CacheEvict(value = ${businessCode}Service.BEAN_ID, allEntries = true)
	public ${entityMapper.code}Dto save${entityMapper.code}ByIdOrCode(@NonNull ${entityMapper.code}Dto save${entityMapper.code}) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(save${entityMapper.code}, CommonDtoAttributes.code.name());
	
		final ${entityMapper.code}Dto old${entityMapper.code} = this.${entityMapper.code?uncap_first}Dao.findByCode(${entityMapper.code}Dto.class,
				save${entityMapper.code}, null, whereAndEqProperties);

		if (old${entityMapper.code} == null) {
			save${entityMapper.code}.setId(UUID.randomUUID().toString());
		
			this.${entityMapper.code?uncap_first}Dao.insertByCode(save${entityMapper.code});
			
			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(save${entityMapper.code});

			return this.${entityMapper.code?uncap_first}Dao.findByCode(${entityMapper.code}Dto.class, save${entityMapper.code}, null, notNullIdProperties);
		}
		
		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(), CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		save${entityMapper.code});
		
		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(save${entityMapper.code}, old${entityMapper.code}, 
		useProperties);
		
		if (ArrayUtils.isEmpty(updateProperties)) {
			return old${entityMapper.code};
		}
		
		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(old${entityMapper.code});

		com.cardone.common.utils.BeanUtils.copyProperties(old${entityMapper.code}, save${entityMapper.code}, notNullIdProperties);

		this.${entityMapper.code?uncap_first}Dao.updateByCode(save${entityMapper.code}, updateProperties, notNullIdProperties);

		return this.${entityMapper.code?uncap_first}Dao.findByCode(${entityMapper.code}Dto.class, old${entityMapper.code}, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = ${businessCode}Service.BEAN_ID, allEntries = true)
	public ${entityMapper.code}Dto save${entityMapper.code}ByName(@NonNull ${entityMapper.code}Dto save${entityMapper.code}) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(save${entityMapper.code}, CommonDtoAttributes.code.name());
	
		final ${entityMapper.code}Dto old${entityMapper.code} = this.${entityMapper.code?uncap_first}Dao.findByCode(${entityMapper.code}Dto.class,
				save${entityMapper.code}, null, whereAndEqProperties);

		if (old${entityMapper.code} == null) {
			save${entityMapper.code}.setId(UUID.randomUUID().toString());
		
			this.${entityMapper.code?uncap_first}Dao.insertByCode(save${entityMapper.code});
			
			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(save${entityMapper.code});

			return this.${entityMapper.code?uncap_first}Dao.findByCode(${entityMapper.code}Dto.class, save${entityMapper.code}, null, notNullIdProperties);
		}
		
		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
				CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(), CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
				save${entityMapper.code});
		
		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(save${entityMapper.code}, old${entityMapper.code}, 
				useProperties);
		
		if (ArrayUtils.isEmpty(updateProperties)) {
			return old${entityMapper.code};
		}
		
		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(old${entityMapper.code});

		com.cardone.common.utils.BeanUtils.copyProperties(old${entityMapper.code}, save${entityMapper.code}, notNullIdProperties);

		this.${entityMapper.code?uncap_first}Dao.updateByCode(save${entityMapper.code}, updateProperties, notNullIdProperties);

		return this.${entityMapper.code?uncap_first}Dao.findByCode(${entityMapper.code}Dto.class, old${entityMapper.code}, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = ${businessCode}Service.BEAN_ID, allEntries = true)
	public int delete${entityMapper.code}ByCode(@NonNull ${entityMapper.code}Dto delete${entityMapper.code}) {
		return this.${entityMapper.code?uncap_first}Dao.deleteByCode(delete${entityMapper.code}, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = ${businessCode}Service.BEAN_ID, allEntries = true)
	public int delete${entityMapper.code}ByIds(@NonNull ${entityMapper.code}Dto delete${entityMapper.code}) {
		return this.${entityMapper.code?uncap_first}Dao.deleteByIds(delete${entityMapper.code});
	}

	@Override
	@Transactional
	@CacheEvict(value = ${businessCode}Service.BEAN_ID, allEntries = true)
	public int update${entityMapper.code}ByCode(@NonNull ${entityMapper.code}Dto update${entityMapper.code}) {
		return this.${entityMapper.code?uncap_first}Dao.updateByCode(update${entityMapper.code}, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = ${businessCode}Service.BEAN_ID, allEntries = true)
	public int update${entityMapper.code}ByIds(@NonNull ${entityMapper.code}Dto update${entityMapper.code}) {
		return this.${entityMapper.code?uncap_first}Dao.updateByIds(update${entityMapper.code});
	}

	@Override
	@Cacheable(value = ${businessCode}Service.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer read${entityMapper.code}ByCodeNqId(@NonNull ${entityMapper.code}Dto read${entityMapper.code}) {
		return this.${entityMapper.code?uncap_first}Dao.readByCodeNqId(Integer.class, read${entityMapper.code});
	}

	@Override
	@Cacheable(value = ${businessCode}Service.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer read${entityMapper.code}ByName(@NonNull ${entityMapper.code}Dto read${entityMapper.code}) {
		return this.${entityMapper.code?uncap_first}Dao.readByName(Integer.class, null, read${entityMapper.code});
	}

	@Override
	@Cacheable(value = ${businessCode}Service.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public ${entityMapper.code}Dto find${entityMapper.code}ByCode(@NonNull ${entityMapper.code}Dto find${entityMapper.code}) {
		return this.${entityMapper.code?uncap_first}Dao.findByCode(${entityMapper.code}Dto.class, find${entityMapper.code}, null, CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = ${businessCode}Service.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public ${entityMapper.code}Dto find${entityMapper.code}ById(@NonNull ${entityMapper.code}Dto find${entityMapper.code}) {
		return this.${entityMapper.code?uncap_first}Dao.findByCode(${entityMapper.code}Dto.class, find${entityMapper.code}, null, CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = ${businessCode}Service.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<${entityMapper.code}Dto> findList${entityMapper.code}ByCode(@NonNull ${entityMapper.code}Dto findList${entityMapper.code}) {
		return this.${entityMapper.code?uncap_first}Dao.findListByCode(${entityMapper.code}Dto.class, findList${entityMapper.code},
				new String[] {}, new String[] {});
	}

	@Override
	@Cacheable(value = ${businessCode}Service.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<${entityMapper.code}Dto> findList${entityMapper.code}ByName(@NonNull ${entityMapper.code}Dto findList${entityMapper.code}) {
		return this.${entityMapper.code?uncap_first}Dao.findListByName(${entityMapper.code}Dto.class, findList${entityMapper.code});
	}
<#if entityMapper.markController>

	@Override
	@Cacheable(value = ${businessCode}Service.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<${entityMapper.code}Dto> pagination${entityMapper.code}ByCode(@NonNull ${entityMapper.code}Dto pagination${entityMapper.code}) {
		return this.${entityMapper.code?uncap_first}Dao.paginationByCode(${entityMapper.code}Dto.class,
				pagination${entityMapper.code});
	}

	@Override
	@Cacheable(value = ${businessCode}Service.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<Map<String, Object>> pagination${entityMapper.code}ByName(@NonNull ${entityMapper.code}Dto pagination${entityMapper.code}) {
		return this.${entityMapper.code?uncap_first}Dao.paginationByName(pagination${entityMapper.code});
	}
</#if>
</#if>
</#list>
}